// Copyright (c) 2014, Cornell University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of HyperDex nor the names of its contributors may be
//       used to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#ifndef hyperdex_daemon_datalayer_index_state_h_
#define hyperdex_daemon_datalayer_index_state_h_

// HyperDex
#include "daemon/datalayer.h"

using hyperdex::datalayer;

struct datalayer::index_state
{
    index_state() : ri(), ii(), m_usable(0) {}
    index_state(region_id _ri, index_id _ii)
        : ri(_ri), ii(_ii), m_usable(0) {}
    index_state(const index_state& other)
        : ri(other.ri), ii(other.ii)
        , m_usable(other.m_usable) {}
    bool is_usable() { e::atomic::memory_barrier(); return e::atomic::load_64_acquire(&m_usable) == 1; }
    void set_usable() { e::atomic::store_64_release(&m_usable, 1); e::atomic::memory_barrier(); }
    index_state& operator = (const index_state& rhs)
    {
        if (this != &rhs)
        {
            ri = rhs.ri;
            ii = rhs.ii;
            m_usable = rhs.m_usable;
        }

        return *this;
    }
    bool operator < (const region_id& x) const { return ri < x; }

    region_id ri;
    index_id ii;

    private:
        uint64_t m_usable;
};

#endif // hyperdex_daemon_datalayer_index_state_h_
